#include "Graphics.h"
	
Graphics * Graphics::s_g = 0;

Graphics::Graphics()
	: m_iHeight(0), m_iWidth(0)
	, m_bInitialized(false)
	, m_bInitFailed(true)
	, m_bWindowed(true)
{
	m_iAllObjects	= new ILL();
	m_iMenuObjects	= new ILL();

}

/**
 * This function need only be called once during the program
 * It calls sub-routines that initializes various aspects of Graphics
 *
 * @param hWnd is passed so that the device knows which window to draw to
 * @return wether or not the function ran without error
 */
bool Graphics::Init(HWND hWnd, int engineType)
{
	
	if(m_bInitialized)					// prevent this function from being called more than once
		return !m_bInitFailed;

	m_bInitialized = true;				// flag that this function has been called

	// ADD INDEPENDENCE LAYER
	if(!DX.Init(hWnd, 600, 800))
		return false;

	// after all functions have completed successfully, mark this flag as false and return true
	m_bInitFailed = false;
	return true;
}

/**
 * Adds a single object into one of Graphics' draw queue
 * 
 * @param pObj is the object to be pushed into the queue
 * @param queueType determines which queue the object will go into (ie menu object will go into menu queue)
 * @return whether or not the process was successful
 */
bool Graphics::AddObject(BaseObject * pObj,int AssetIndex, int queueType)
{
	if(pObj->GetAssetIndex() == -1) pObj->SetAssetIndex(AssetIndex);
	switch(queueType) {
	case 0:
		m_iAllObjects->Add("BaseObject",(void*)pObj); break;
	case 1:
		m_iMenuObjects->Add("BaseObject",(void*)pObj); break;
	}
	return true;
}
bool Graphics::AddIndexLinkedList(ILL* List, int queueType)
{
	
	switch(queueType) {
	case 0:		m_iAllObjects	= List;	break;//yOUR FUNERAL
	case 1:		m_iMenuObjects	= List;	break;
	}
	return true;
}
/**
 * Adds a single object into one of Graphics' draw queue
 * 
 * @param textureLoc is the filename of the asset
 * @param queueType determines which queue the object will go into (ie menu object will go into menu queue)
 * @return the index of the asset after being put into the queue
 */
int Graphics::AddAsset(char* textureLoc, color cKey)
{
	// ADD INDEPENDENCE LAYER
	return DX.AddAsset(textureLoc, cKey);
}


/**
 * Adds a single object into one of Graphics' draw queue
 * 
 * @param pObj is the object to be removed from Graphics queue
 * @param queueType determines which queue the object will go into (ie menu object will go into menu queue)
 * @return the index of the asset after being put into the queue
 */
void * Graphics::RemoveObject(BaseObject * pObj,int queueType) 
{
	Record * R;
	switch(queueType) {
	case 0:
		R = m_iAllObjects->Remove_by_Value((void*)pObj); break;
	case 1:
		R = m_iMenuObjects->Remove_by_Value((void*)pObj); break;
	}
	return R->Data;
}

bool Graphics::RemoveAsset(int index)
{
	// ADD INDEPENDENCE LAYER
	return DX.RemoveAsset(index);
}

point Graphics::GetAssetDimensions(int index)
{
	// ADD INDEPENDENCE LAYER
	return DX.GetAssetDimensions(index);
}

/**
 * Should be called in the game loop once; draws one frame
 *
 */
void Graphics::Render()
{
	if(!m_bInitialized || m_bInitFailed)
		return;

	// ADD INDEPENDENCE LAYER
	DX.Render(m_iAllObjects, m_iMenuObjects);

	/*DX.BeginScene();
	DX.BeginSprite();
	DX.Render(m_iAllObjects);
	DX.RenderMenu(m_iMenuObjects);
	DX.EndSprite();
	DX.RenderMenuText();
	DX.EndScene();*/
}

void Graphics::Release()
{
	DX.Release();
}

/*
 * Simply calls the release function of Graphics to ensure that there are no memory leaks
 */
Graphics::~Graphics()
{
	//Graphics::Release();
}